class SimpleMathQuestion {
    static types = ['＋', '－', '×', '÷']
    get probability() {
        return 10;
    }
    random() {
        let type = SimpleMathQuestion.types[Math.floor(Math.random() * SimpleMathQuestion.types.length)];
        let left, right, result;
        switch (type) {
            case '＋':
                left = Math.floor(Math.random() * 90);
                right = Math.floor(Math.random() * (90 - left));
                result = left + right;
                break;
            case '－':
                left = Math.floor(Math.random() * 90) + 10;
                right = Math.floor(Math.random() * left);
                result = left - right;
                break;
            case '×':
                left = Math.floor(Math.random() * 20);
                right = Math.floor(Math.random() * Math.floor(100 / Math.max(left, 1)));
                result = left * right;
                break;
            case '÷':
                result = Math.floor(Math.random() * 100);
                right = Math.floor(Math.random() * Math.floor(100 / Math.max(result, 1) - 1)) + 1;
                left = result * right;
                break;
        }
        let answers = [];
        for (let i = 0; i < 9; i ++) {
            let answer = Math.floor(100 * Math.random());
            while (answers.includes(answer) || answer === result) {
                answer = Math.floor(100 * Math.random());
            }
            answers.push(answer);
        }
        answers[Math.floor(answers.length * Math.random())] = result;
        return {
            question: {
                title: left + type + right + '＝？'
            },
            answers: answers.map(answer => ({
                title: answer,
                right: result === answer
            }))
        }
    }
}

class ColorQuestion {
    static colors = [
        {
            title: '红色',
            color: '#FF0000'
        },
        {
            title: '绿色',
            color: '#00FF00'
        },
        {
            title: '黄色',
            color: '#FFFF00'
        },
        {
            title: '蓝色',
            color: '#0000ff'
        },
        {
            title: '紫色',
            color: '#ff00ff'
        },
        {
            title: '黑色',
            color: '#000000'
        },
        {
            title: '白色',
            color: '#ffffff'
        }
    ];
    static types = [
        '背景是什么颜色？',
        '文字是什么颜色？',
        '请选择文字:',
        '的文字在哪里？'
    ];
    get probability() {
        return 10;
    }
    random() {
        let typeIndex = Math.floor(Math.random() * ColorQuestion.types.length);
        let type = ColorQuestion.types[typeIndex];

        let colorIndex = Math.floor(Math.random() * ColorQuestion.colors.length);
        let result = ColorQuestion.colors[colorIndex];
        let disturbColors = [...ColorQuestion.colors.slice(0, colorIndex), ...ColorQuestion.colors.slice(colorIndex + 1)];

        let questionColorIndex = Math.floor(Math.random() * ColorQuestion.colors.length);
        let questionColor = ColorQuestion.colors[questionColorIndex];
        let disturbQuestionColors = [...ColorQuestion.colors.slice(0, questionColorIndex), ...ColorQuestion.colors.slice(questionColorIndex + 1)];

        let answers = [];

        for (let i = 0; i < 9; i++) {
            answers.push({
                title: disturbColors[Math.floor(Math.random() * disturbColors.length)].title,
                style: 'color:' + disturbColors[Math.floor(Math.random() * disturbColors.length)].color
            })
        }

        if (typeIndex === 0) {

            answers[Math.floor(answers.length * Math.random())].title = result.title;

            return {
                question: {
                    title: type,
                    style: 'background-color:' + result.color + ';color:' + disturbColors[Math.floor(Math.random() * disturbColors.length)].color
                },
                answers: answers.map(answer => ({
                    ...answer,
                    right: answer.title === result.title
                }))
            }

        } else if (typeIndex === 1) {

            answers[Math.floor(answers.length * Math.random())].title = result.title;

            return {
                question: {
                    title: type,
                    style: 'background-color:' + disturbColors[Math.floor(Math.random() * disturbColors.length)].color + ';color:' + result.color
                },
                answers: answers.map(answer => ({
                    ...answer,
                    right: answer.title === result.title
                }))
            }

        } else if (typeIndex === 2) {

            answers[Math.floor(answers.length * Math.random())].title = result.title;

            return {
                question: {
                    title: type + result.title,
                    style: 'background-color:' + questionColor.color + ';color:' + disturbQuestionColors[Math.floor(Math.random() * disturbQuestionColors.length)].color
                },
                answers: answers.map(answer => ({
                    ...answer,
                    right: answer.title === result.title
                }))
            }

        } else if (typeIndex === 3) {

            answers[Math.floor(answers.length * Math.random())].style = 'color:' + result.color;

            return {
                question: {
                    title: result.title + type,
                    style: 'background-color:' + questionColor.color + ';color:' + disturbQuestionColors[Math.floor(Math.random() * disturbQuestionColors.length)].color
                },
                answers: answers.map(answer => ({
                    ...answer,
                    right: answer.style === 'color:' + result.color
                }))
            }

        }
    }
}

class ShapeQuestion {
    static hollow = '△▽○▱□◁▷◿◹◺◸';
    static solids = '▲▼●▰■◀▶◢◥◣◤';
    static all = ShapeQuestion.hollow + ShapeQuestion.solids;
    static types = [
        '中不包括以下哪种图形？',
        '中含有以下哪种图形？',
        '的空心图案为？',
        '的实心图案为？',
    ];
    get probability() {
        return 10;
    }
    random() {
        let typeIndex = Math.floor(Math.random() * ShapeQuestion.types.length);
        let type = ShapeQuestion.types[typeIndex];

        if (typeIndex === 0) {
            let result = ShapeQuestion.all.charAt(Math.floor(ShapeQuestion.all.length * Math.random()));
            let others = ShapeQuestion.all.replace(result, '');

            let tips = '';
            for (let i = 0; i < 4; i++) {
                let char = others.charAt(Math.floor(others.length * Math.random()));
                tips += char;
                others.replace(char, '');
            }
            let answers = [];
            for (let i = 0; i < 9; i++) {
                answers.push(tips.charAt(Math.floor(tips.length * Math.random())));
            }
            answers[Math.floor(answers.length * Math.random())] = result;

            return {
                question: {
                    title: tips + type
                },
                answers: answers.map(answer => ({
                    title: answer,
                    right: answer === result
                }))
            }
        } else if (typeIndex === 1) {
            let result = ShapeQuestion.all.charAt(Math.floor(ShapeQuestion.all.length * Math.random()));
            let others = ShapeQuestion.all.replace(result, '');

            let tips = [];
            for (let i = 0; i < 4; i++) {
                let char = others.charAt(Math.floor(others.length * Math.random()));
                tips.push(char);
                others.replace(char, '');
            }
            tips[Math.floor(tips.length * Math.random())] = result;
            tips = tips.join('');

            let answers = [];
            for (let i = 0; i < 9; i++) {
                answers.push(others.charAt(Math.floor(tips.length * Math.random())));
            }
            answers[Math.floor(answers.length * Math.random())] = result;

            return {
                question: {
                    title: tips + type
                },
                answers: answers.map(answer => ({
                    title: answer,
                    right: answer === result
                }))
            }
        } else if (typeIndex === 2) {
            let resultIndex = Math.floor(ShapeQuestion.hollow.length * Math.random());
            let result = ShapeQuestion.hollow.charAt(resultIndex);
            let tip = ShapeQuestion.solids.charAt(resultIndex);

            let others = ShapeQuestion.all.replace(result, '');
            let answers = [];
            for (let i = 0; i < 9; i++) {
                answers.push(others.charAt(Math.floor(others.length * Math.random())));
            }
            answers[Math.floor(answers.length * Math.random())] = result;

            return {
                question: {
                    title: tip + type
                },
                answers: answers.map(answer => ({
                    title: answer,
                    right: answer === result
                }))
            }
        } else if (typeIndex === 3) {
            let resultIndex = Math.floor(ShapeQuestion.solids.length * Math.random());
            let result = ShapeQuestion.solids.charAt(resultIndex);
            let tip = ShapeQuestion.hollow.charAt(resultIndex);

            let others = ShapeQuestion.all.replace(result, '');
            let answers = [];
            for (let i = 0; i < 9; i++) {
                answers.push(others.charAt(Math.floor(others.length * Math.random())));
            }
            answers[Math.floor(answers.length * Math.random())] = result;

            return {
                question: {
                    title: tip + type
                },
                answers: answers.map(answer => ({
                    title: answer,
                    right: answer === result
                }))
            }
        }
    }
}

class DirectionQuestion {
    static directions = [ '←', '↖', '↑', '↗', '→', '↘', '↓', '↙' ];
    static types = [
        '的右前方为？',
        '的右方为？',
        '的右后方为？',
        '的后方为？',
        '的左后方为？',
        '的左方为？',
        '的左前方为？',
    ];
    static prefix = '地图上，';
    get probability() {
        return 10;
    }
    random() {
        let typeIndex = Math.floor(Math.random() * DirectionQuestion.types.length);
        let type = DirectionQuestion.types[typeIndex];

        let questionIndex = Math.floor(Math.random() * DirectionQuestion.directions.length);
        let question = DirectionQuestion.directions[questionIndex];

        let resultIndex = (questionIndex + typeIndex + 1) % DirectionQuestion.directions.length;
        let result = DirectionQuestion.directions[resultIndex];

        let disturbs = [...DirectionQuestion.directions.slice(0, resultIndex), ...DirectionQuestion.directions.slice(resultIndex + 1)];
        let answers = [];
        for (let i = 0; i < 9; i++) {
            answers.push(disturbs[Math.floor(Math.random() * disturbs.length)]);
        }
        answers[Math.floor(Math.random() * answers.length)] = result;

        return {
            question: {
                title: DirectionQuestion.prefix + question + type
            },
            answers: answers.map(answer => ({
                title: answer,
                right: answer === result
            }))
        }
    }
}

class Question {
    static factories = [new SimpleMathQuestion(), new ColorQuestion(), new ShapeQuestion(), new DirectionQuestion()].flatMap(factory => new Array(factory.probability).fill(factory));
    static random() {
        let factory = Question.factories[Math.floor(Math.random() * Question.factories.length)];
        return factory.random();
    }
    random() {
        return {
            question: {
                title: ''
            },
            answers: []
        }
    }
}

module.exports = Question;
